#include "can.h"
#include <QThread>
#include "candatabase.h"
#include "cre_mes.h"


GCcancls::GCcancls()//构造函数//初始化变量
{

}
void GCcancls::DataReceive()
{
    if (musbcanstart==true)
    {
        qDebug()<<"进入接收循环";
        while(!stopped)//死循环//
        {

            if(GetReceiveNum(devtype,devind,canind)==0)
            {
                QThread::msleep(1);
            }else {
                ReceiveCANThread();//接收数据
            }


        }
        stopped = false;
        qDebug()<<"退出接收循环";
    }else {
        qDebug()<<"进入接收循环判断没过";
    }

}

void GCcancls::stop()
{
    stopped = true;
}

void GCcancls::ReceiveCANThread()//接收数据线程
{
    bool ok;
    ERR_INFO vei;
    CAN_OBJ preceive[21];
    ULONG res = 10;

    res=Receive(devtype,devind,canind,preceive,20,0);
    if(res==0xFFFFFFFF)
    {
        if(ReadErrInfo(devtype,devind,canind,&vei)!=STATUS_ERR)
        {
            qDebug()<<"读取数据失败!"<<"错误码为："<<QString::number(vei.ErrCode,16);
            return;
        }
    }

    for(int i=0;i<res;i++)
    {
        QByteArray  bytearr;
        for (int a=0;a<preceive[i].DataLen;a++)
        {
            bytearr.append(preceive[i].Data[a]);
        }
        //    emit my_signal_CHN0(receive_str);//子线程处理完毕//触发自定义的信号
        CanDataBase *cdb=new CanDataBase();
        cdb->SetData(preceive[i].ID,bytearr,preceive[i].DataLen,preceive[i].ExternFlag,preceive[i].RemoteFlag);
        cdb->SetTime(preceive[i].TimeStamp);
        cdb->ZCAN_data.timestamp=preceive[i].TimeStamp;
        cdb->ZCAN_data.frame.can_id=preceive[i].ID;
        cdb->ZCAN_data.frame.can_dlc=preceive[i].DataLen;
        for (int var = 0; var < preceive[i].DataLen; ++var) {
            cdb->ZCAN_data.frame.data[var]=preceive[i].Data[var];
        }
       emit this->DataUpdata(cdb);
        if(cdb->IsCCP_protocol)
        {
            if(CRE_Mes::REV_Data_response(cdb,this->currentSendMsg))
            {
                qDebug()<<"true";
                if((this->currentSendMsg!=nullptr) && (this->currentSendMsg->sem!=nullptr))
                {
                    this->currentSendMsg->sem->release();
                }
                delete this->currentSendMsg;
                this->currentSendMsg=nullptr;
            }
        }
        if(cdb->Id==Rev_UDS_CANID)
        {

            emit UDS_RevData_Sig(cdb);
        }


        //qDebug()<<__func__<<__LINE__<<res<<cdb->StrData;
    }

}

bool GCcancls::TransmitCANThread(unsigned int id,unsigned char *ch,bool EXT,bool RTR, unsigned int len,int sendtype,CanDataBase *cdb)//发送数据线程
{
    current_CTR=(current_CTR+1)&0xFF;
    cdb->_data[1]=this->current_CTR&0xFF;
    cdb->GetStringData();
    CAN_OBJ psend;
    //发送
    ULONG Tr;
    psend.ID=id;//ID号//需要实际填写//
    psend.SendType=sendtype;
    psend.RemoteFlag=RTR;
    psend.ExternFlag=EXT;
    psend.DataLen=len;
    for (int i=0; i < len; i++)
    {
        psend.Data[i]=ch[i];
    }

    Tr=Transmit(devtype,devind,canind,&psend,1);//返回实际发送的帧数
    //devtype设备类型号//devind设备索引号//canind第几路CAN//&psend要发送的数据帧数组的首指针//1要发送的数据帧数组的长度//
    if(Tr==STATUS_ERR){
        //未发送成功
        return  false;
    }
    else{
        this->currentSendMsg=cdb;
        return  true;
    }
}
uint GCcancls::TransmitCANThread(ZCAN_Transmit_Data* pTransmit, UINT len)
{

    CAN_OBJ *psend=new CAN_OBJ[len];
    for (int var = 0; var < len; ++var) {
        psend[var].ID=GET_ID( pTransmit[var].frame.can_id);
        psend[var].SendType=0;
        psend[var].RemoteFlag=IS_RTR( pTransmit[var].frame.can_id);
        psend[var].ExternFlag=IS_EFF( pTransmit[var].frame.can_id);
        psend[var].DataLen=pTransmit[var].frame.can_dlc;
        for (int i=0; i < pTransmit[var].frame.can_dlc; i++)
        {
            psend[var].Data[i]=pTransmit[var].frame.data[i];     
        }
    }
    uint  Tr=Transmit(devtype,devind,canind,psend,len);//返回实际发送的帧数
    delete [] psend;
    return Tr;
}



bool GCcancls::TransmitCANThread(CanDataBase *cdb)
{
    unsigned int id=cdb->Id;
    unsigned char *ch=(unsigned char *)cdb->_data.data();
    bool EXT=cdb->IsExtendFrame;
    bool RTR=cdb->IsRemoteFrame;
    unsigned int len=cdb->Len;
    return     TransmitCANThread(id,ch,EXT,RTR,len,cdb->transmit_type,cdb);
}

bool GCcancls::OpenCANThread(int baud)//打开设备
{

    bool ok;
    ERR_INFO vei;
    CAN_OBJ preceive[100];
    //    CAN_OBJ psend;
    //    int baud=0x10000000;//参数有关数据缓冲区地址首指针
    //      int pdata=0x00;//参数有关数据缓冲区地址首指针
    //打开设备
    musbcanstart=false;

    if(OpenDevice(devtype,devind,res)==STATUS_ERR )//为1表示操作成功，0表示操作失败。
    {
        QThread::msleep(500);
        if(ReadErrInfo(devtype,devind,canind,&vei)!=STATUS_ERR)
        {
            qDebug()<<"打开失败："<<QString::number(vei.ErrCode,16);
        }
        IsfindandOpenFlag=false;
        return false;
    }
    else
    {
        IsfindandOpenFlag=true;
        //      qDebug()<<"OpenDevice successed";
    }
    //初始化
    INIT_CONFIG init_config;//INIT_CONFIG
    init_config.Mode=0;//0正常模式//1为只听模式//2为自发自收模式//
    init_config.Filter=0;//滤波方式，单滤波
    switch(baud)
    {

    case 500*1000: //500

        init_config.Timing0 = 0;
        init_config.Timing1 = 0x1c;
        break;

    case 250*1000://250

        init_config.Timing0 = 0x01;
        init_config.Timing1 = 0x1c;
        break;

    default:
        init_config.Timing0 = 0;
        init_config.Timing1 = 0x1c;
        break;
    }//设置错误，默认为500K

    init_config.AccCode=0x000000;//验收码
    init_config.AccMask=0xFFFFFF;//屏蔽码
    QThread::msleep(100);
    if(InitCAN(devtype,devind,canind,&init_config)==STATUS_ERR)
    {
        qDebug()<<"Init Error";
        CloseDevice(devtype,devind);
        return false;
    }

    if(StartCAN(devtype,devind,canind)==STATUS_ERR){
        qDebug()<<"start fail";
        CloseDevice(devtype,devind);
        return false;
    }else
    {
        qDebug()<<"start successed";
        musbcanstart=true;
        ClearBuffer(devtype,devind,canind);
        return  true;
    }
}

void GCcancls::CloseCANThread()
{
    CloseDevice(devtype,devind);
    qDebug()<<"gccan-closed";
}
